package cn.fsd.service.impl;

import cn.fsd.domain.*;
import cn.fsd.mapper.StoreRoomMapper;
import cn.fsd.mapper.Storeroom_commodityMapper;
import cn.fsd.mapper.TempMapper;
import cn.fsd.nacos.CustomerServer;
import cn.fsd.nacos.DispatchServer;
import cn.fsd.query.dispatch.TransferQuery;
import cn.fsd.query.storeroom.TaskQuery;
import cn.fsd.service.StoreRoomService;
import cn.fsd.util.RedisKey;
import cn.fsd.util.StoreroomRedisUtils;
import cn.fsd.vo.storeroom.TransferInfoVO;
import cn.fsd.vo.storeroom.deliveryOut.TaskTransferCommodityVO;
import cn.fsd.vo.storeroom.exchange.checkIn.TaskRecordCommodityVO;
import cn.fsd.vo.storeroom.exchange.out.TaskCommodityVO;
import cn.fsd.vo.storeroom.transfer.DistributeInfoVO;
import cn.fsd.vo.storeroom.transfer.TransferOutInfoVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class StoreRoomServiceImpl implements StoreRoomService {

    final
    Storeroom_commodityMapper storeroom_commodityMapper;

    final
    StoreroomRedisUtils redisUtil;

    final
    StoreRoomMapper storeRoomMapper;
    final
    DispatchServer dispatchServer;

    final
    CustomerServer customerServer;

    final
    TempMapper tempMapper;

    public StoreRoomServiceImpl(Storeroom_commodityMapper storeroom_commodityMapper, StoreroomRedisUtils storeroomRedisUtils, StoreRoomMapper storeRoomMapper, DispatchServer dispatchServer, CustomerServer customerServer, TempMapper tempMapper) {
        this.storeroom_commodityMapper = storeroom_commodityMapper;
        this.redisUtil = storeroomRedisUtils;
        this.storeRoomMapper = storeRoomMapper;
        this.dispatchServer = dispatchServer;
        this.customerServer = customerServer;
        this.tempMapper = tempMapper;
    }

    @Override
    public Integer getMaxLimitation(String delivery_address, String commodity_id) {
        String storeroom_id = dispatchServer.getStoreroom(delivery_address).getData();
        System.out.println("getMaxLimitation commodity_id= "+commodity_id);
        System.out.println("getMaxLimitation delivery_address= "+delivery_address);
        System.out.println("getMaxLimitation storeroom_id= "+storeroom_id);
        return storeroom_commodityMapper.getMaxLimitation(storeroom_id, commodity_id);
    }

    /**
     * 计算缺货订单缺货的数量，计入到storeroom_commodity表中的Out_of_stock字段，然后将订单加入到缺货队列
     */
    @Override
    public void stockOutOP(Order order) {
        Integer outOfStock;
        Storeroom_commodity storeroom_commodity =
                storeroom_commodityMapper.selectByPrimaryKey(order.getCommodity_id(), getStoreroomId(order));
        if (redisUtil.isListEmpty(getQueueKey(order))) {
            outOfStock = order.getCommodity_num();
        } else {
            outOfStock = order.getCommodity_num() - storeroom_commodity.getTransferable_num();
        }
        System.out.println("outOfStock="+outOfStock);
        storeroom_commodity.setOut_of_stock(storeroom_commodity.getOut_of_stock() + outOfStock);
        storeroom_commodityMapper.updateByPrimaryKey(storeroom_commodity);
        redisUtil.queueIn(getQueueKey(order), order.getOrder_id());
    }

    /**
     * 撤销订单<br/>
     * 订单状态为“缺货”：从缺货量中减去订单商品数量，加入撤销订单集合<br/>
     * 订单状态为“已挂起”或“可分配”：从已分配量中减去商品数量，加到可分配量<br/>
     */
    @Override
    public void cancelOrder(Order order) {
        Storeroom_commodity storeroom_commodity =
                storeroom_commodityMapper.selectByPrimaryKey(order.getCommodity_id(), getStoreroomId(order));
        if (order.getOrder_status().equals("缺货")) {
            storeroom_commodity.setOut_of_stock(storeroom_commodity.getOut_of_stock() - order.getCommodity_num());
            redisUtil.sSet(RedisKey.getCanceledOrderSetKey(), order.getOrder_id());
        } else {
            storeroom_commodity.setTransferred_num(storeroom_commodity.getTransferred_num() - order.getCommodity_num());
            storeroom_commodity.setTransferable_num(storeroom_commodity.getTransferable_num() + order.getCommodity_num());
        }
        storeroom_commodityMapper.updateByPrimaryKey(storeroom_commodity);
    }

    /**
     * 为一个订单完成货物分配，订单状态将变为“已挂起”<br/>
     * 若该订单为缺货后分配，则需要从缺货数中减去分配数。
     *
     * @param order
     */
    @Override
    public void handle(Order order) {
        Storeroom_commodity storeroom_commodity =
                storeroom_commodityMapper.selectByPrimaryKey(order.getCommodity_id(), getStoreroomId(order));
        if (order.getDelivery_status().equals("缺货")) {
            storeroom_commodity.setOut_of_stock(storeroom_commodity.getOut_of_stock() - order.getCommodity_num());
        }
        storeroom_commodity.setTransferable_num(storeroom_commodity.getTransferable_num() - order.getCommodity_num());
        storeroom_commodity.setTransferred_num(storeroom_commodity.getTransferred_num() + order.getCommodity_num());
        storeroom_commodityMapper.updateByPrimaryKey(storeroom_commodity);
    }

    @Override
    public Storeroom getInfo(String storeroom_id) {
        return storeRoomMapper.selectByPrimaryKey(storeroom_id);
    }

    @Override
    public PageInfo<TransferOutInfoVO> getTransferOutInfo(TransferQuery transferQuery) {
        PageHelper.startPage(transferQuery.getPageNow(), transferQuery.getPageSize());
        List<TransferOutInfoVO> transferOutInfo = tempMapper.getTransferOutInfo(transferQuery);
        return new PageInfo<>(transferOutInfo);
    }

    @Override
    public PageInfo<DistributeInfoVO> getDistributeInfo(TransferQuery transferQuery) {
        PageHelper.startPage(transferQuery.getPageNow(), transferQuery.getPageSize());
        return new PageInfo<>(tempMapper.getDistributeInfo(transferQuery));
    }

    @Override
    public PageInfo<TaskRecordCommodityVO> findExchangeCheckIn(TaskQuery taskQuery) {
        PageHelper.startPage(taskQuery.getPageNow(),taskQuery.getPageSize());
        return new PageInfo<>(tempMapper.findExchangeCheckIn(taskQuery));
    }

    @Override
    public PageInfo<TaskCommodityVO> findExchangeOut(TaskQuery taskQuery) {
        taskQuery.setOrder_status("分站库房退货入库");
        PageHelper.startPage(taskQuery.getPageNow(),taskQuery.getPageSize());
        return new PageInfo<>(tempMapper.findExchangeMainStation(taskQuery));
    }

    @Override
    public PageInfo<TaskCommodityVO> findExchangeIn(TaskQuery taskQuery) {
        taskQuery.setOrder_status("分站库房退货出库");
        PageHelper.startPage(taskQuery.getPageNow(),taskQuery.getPageSize());
        return new PageInfo<>(tempMapper.findExchangeSubstation(taskQuery));
    }

    @Override
    public PageInfo<TaskCommodityVO> findExchangeCenter(TaskQuery taskQuery) {
        taskQuery.setOrder_status("中心库房退货入库");
        PageHelper.startPage(taskQuery.getPageNow(),taskQuery.getPageSize());
        return new PageInfo<>(tempMapper.findExchangeMainStation(taskQuery));
    }

    @Override
    public PageInfo<TaskTransferCommodityVO> findDeliveryOut(TaskQuery query) {
        PageHelper.startPage(query.getPageNow(),query.getPageSize());
        return new PageInfo<>(tempMapper.findDeliveryOut(query));
    }

    /**
     * 远程调用dispatchServer，在订单创建之前使用
     *
     * @return true代表缺货
     */
    @Override
    public Boolean checkStockOut(String delivery_address, String commodity_id, Integer commodity_num) {
        String storeroom_id = dispatchServer.getStoreroom(delivery_address).getData();
        System.out.println("checkStockOut commodity_id= "+commodity_id);
        System.out.println("checkStockOut delivery_address= "+delivery_address);
        System.out.println("checkStockOut storeroom_id= "+storeroom_id);
        if (!redisUtil.isListEmpty(getQueueKey(storeroom_id, commodity_id))) return true;
        Storeroom_commodity storeroom_commodity = storeroom_commodityMapper.selectByPrimaryKey(commodity_id, storeroom_id);
        return storeroom_commodity.getTransferable_num() < commodity_num;
    }

    @Override
    public Boolean checkStockOutByStoreroomId(String storeroom_id, String commodity_id, Integer commodity_num) {
        System.out.println("checkStockOutByStoreroomId commodity_id= "+commodity_id);
        System.out.println("checkStockOutByStoreroomId commodity_id= "+commodity_id);
        System.out.println("checkStockOutByStoreroomId storeroom_id= "+storeroom_id);
        if (!redisUtil.isListEmpty(getQueueKey(storeroom_id, commodity_id))) return true;
        Storeroom_commodity storeroom_commodity = storeroom_commodityMapper.selectByPrimaryKey(commodity_id, storeroom_id);
        return storeroom_commodity.getTransferable_num() < commodity_num;
    }

    private String getStoreroomId(Order order) {
        Transfer transfer = dispatchServer.findByOrderId(order.getOrder_id());
        return transfer.getStoreroom_id();
    }

    private String getQueueKey(Order order) {
        return RedisKey.getStockOutOrderQueueKey(getStoreroomId(order), order.getCommodity_id());
    }

    private String getQueueKey(String storeroom_id, String commodity_id) {
        return RedisKey.getStockOutOrderQueueKey(storeroom_id, commodity_id);
    }

    /**
     *根据换货订单id查到换货订单
     * 新建任务单，设置id为换货订单id
     * 根据换货订单id查送货任务单，从而得到分站
     * 任务单设置：分站，商品数量，类型“退货”，状态“已调度”，之后需要分站进行分配，任务单状态变为“已分配”，订单状态为“开始退货”
     * 退换货记录：旧订单id：换货订单id，任务单id：退货任务单id
     */
    @Override
    public void beginExchange(String order_id) {
        Order order = tempMapper.getOrderById(order_id);
        Task task=new Task();
        task.setTask_id(UUID.randomUUID().toString());
        task.setOrder_id(order.getOrder_id());
        //查订单的换货任务单，从而得到分站
        task.setStation_id(tempMapper.findTaskByOrderId(order.getOrder_id()).getStation_id());
        task.setTask_genDate(new Date());
        task.setCount_inTask(order.getCommodity_num());//商品数量
        task.setTask_status("已调度");//任务状态
        // TODO: 2023/7/16 加入到分站体系中
        task.setCourier_id("-1");//配送员在分站管理的任务分配时指定
        //任务类型根据订单类型判断：新订订单对应送货任务，退换货订单对应相同任务名，退订不产生任务单
        task.setTask_type("退货");
        //********以下字段需要根据需求设置*********
        task.setTask_finDate(new Date());//要求完成日期
        task.setTask_deliveryDate(new Date());//送货日期
        tempMapper.insertTask(task);

        //根据换货订单，生成退换货记录，旧订单记录为该换货订单
        Exchange_record exchange_record = new Exchange_record();
        exchange_record.setCustomer_id(order.getCustomer_id());
        exchange_record.setExchange_id(String.valueOf(UUID.randomUUID()));
        exchange_record.setOld_order_id(order.getOrder_id());
        exchange_record.setNew_task_id(task.getTask_id());
        exchange_record.setReason("订单："+order.getOrder_id()+"的退货记录");
        exchange_record.setExchange_num(order.getCommodity_num());
        exchange_record.setExchange_money(order.getOrder_total_amount());
        exchange_record.setExchange_date(new Date());
        tempMapper.insertExchangeRecord(exchange_record);
    }

    @Override
    public TransferInfoVO findTransferById(String transfer_id) {
        return tempMapper.findTransferById(transfer_id);
    }
}
